This demo shows how recursive DFS uses the call stack to manage the current path and when pre/post actions happen (discovery/finish).
dfs_recursive.py
def dfs(u):
color[u] = GRAY # discover (pre)
time += 1; d[u] = time
for v in adj[u]:
if color[v] == WHITE:
parent[v] = u; dfs(v)
color[u] = BLACK # finish (post)
time += 1; f[u] = time
Tip: GRAY = currently exploring; BLACK = finished. Discovery/finish times wrap children, forming the parenthesis structure.